package com.fushenlan.epidemicControl.service.Impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fushenlan.Vo.InhabitInfoVo;
import com.fushenlan.commons.ApiGlobalErrorDefinition;
import com.fushenlan.commons.CheckParamUtil;
import com.fushenlan.commons.GeneralResponse;
import com.fushenlan.epidemicControl.dto.InhabitantInfoDto;
import com.fushenlan.epidemicControl.mapper.BuildingInfoMapper;
import com.fushenlan.epidemicControl.mapper.InhabitantInfoMapper;
import com.fushenlan.epidemicControl.mapper.NeighborhoodInfoMapper;
import com.fushenlan.epidemicControl.service.InhabitantInfoService;
import com.fushenlan.excel.ExportExcelUtil;
import com.fushenlan.po.BuildingInfo;
import com.fushenlan.po.InhabitantInfo;
import com.fushenlan.po.NeighborhoodInfo;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author XUJIN
 * @DATE 2022/4/21
 * @PACKAGE_NAME com.fushenlan.epidemicControl.service.Impl
 * @VERSION 1.0
 */
@Service
@Slf4j
public class InhabitInfoServiceImpl implements InhabitantInfoService {


    private static  final String EXPORT_INHABIT_FILENAME = "居委会所属居民信息模板";
    private static  final String EXPORT_INHABIT_TITLE = "居委会下属居民信息表";

    @Autowired
    private InhabitantInfoMapper inhabitantInfoMapper;

    @Autowired
    private BuildingInfoMapper buildingInfoMapper;

    @Autowired
    private NeighborhoodInfoMapper neighborhoodInfoMapper;


    /**
     * 获取居民列表
     *
     * @param infoDto
     * @return
     */
    @Override
    public List<InhabitInfoVo> findInhabitList(InhabitantInfoDto infoDto) {

        if (StringUtils.isNotEmpty(infoDto.getCommunityName())){
            BuildingInfo bi = new BuildingInfo();
            bi.setName(infoDto.getCommunityName())
                            .setLevel(1);
            List<BuildingInfo> list = buildingInfoMapper.findList(bi);
            if (CollectionUtil.isNotEmpty(list)){
                infoDto.setResidentialId(list.get(0).getId());
            }
        }

        List<InhabitInfoVo> inhabitInfoVos = inhabitantInfoMapper.findInhabitList(infoDto);
        for (InhabitInfoVo inhabitInfoVo : inhabitInfoVos){
            StringBuilder sb = new StringBuilder("");
            //获取小区信息
            BuildingInfo buildingInfo = new BuildingInfo();
            buildingInfo.setId(inhabitInfoVo.getResidentialId())
                            .setLevel(1);
            List<BuildingInfo> list1 = buildingInfoMapper.findList(buildingInfo);
            if (CollectionUtil.isNotEmpty(list1)){
                sb.append(list1.get(0).getName());
            }
            //获取楼栋号信息
            BuildingInfo buildingNoInfo = new BuildingInfo();
            buildingNoInfo.setId(inhabitInfoVo.getBuildingId())
                    .setLevel(2);
            List<BuildingInfo> list2 = buildingInfoMapper.findList(buildingNoInfo);
            if (CollectionUtil.isNotEmpty(list2)){
                sb.append(list2.get(0).getName());
            }

            //获取房间号
            BuildingInfo roomNoInfo = new BuildingInfo();
            buildingNoInfo.setId(inhabitInfoVo.getHouseId())
                    .setLevel(3);
            List<BuildingInfo> list3 = buildingInfoMapper.findList(buildingNoInfo);
            if (CollectionUtil.isNotEmpty(list3)){
                sb.append(list3.get(0).getName());
            }
            inhabitInfoVo.setAddress(sb.toString());

        }
        return inhabitInfoVos;
    }

    /**
     * 添加居民信息
     * @param inhabitantInfoDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public GeneralResponse addInhabitInfo(InhabitantInfoDto inhabitantInfoDto) {


        //判断身份证不能重复
        QueryWrapper<InhabitantInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("identifyNo",inhabitantInfoDto.getIdentifyNo());
        inhabitantInfoMapper.selectList(wrapper);
        List<InhabitantInfo> inhabitList =  inhabitantInfoMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(inhabitList)){
            return GeneralResponse.fail(ApiGlobalErrorDefinition.USER_EXISTD);
        }
        //添加居民信息
        InhabitantInfo info = new InhabitantInfo();
        info.setUserName(inhabitantInfoDto.getUserName())
                .setFamilyId(0)
                .setIdentifyNo(inhabitantInfoDto.getIdentifyNo())
                .setIdentifyType(inhabitantInfoDto.getIdentifyType())
                .setPhoneNumber(inhabitantInfoDto.getPhoneNumber())
                .setNeighborhoodId(inhabitantInfoDto.getNeighborhoodId());
        NeighborhoodInfo neighborhoodInfo = neighborhoodInfoMapper.selectById(inhabitantInfoDto.getNeighborhoodId());
        if (neighborhoodInfo != null){
            info.setStreetCode(neighborhoodInfo.getStreetCode());
        }
        //设置居民用户地址时，需根据传入的楼栋表 level = 3 的行id
        if (inhabitantInfoDto.getHouseId() != null){
            info.setHouseId(inhabitantInfoDto.getHouseId());
            BuildingInfo bo = new BuildingInfo();
            bo.setLevel(3);
            bo.setId(inhabitantInfoDto.getHouseId());
            //获取到房间号信息  housed
            List<BuildingInfo> list = buildingInfoMapper.findList(bo);
            if (CollectionUtil.isNotEmpty(list)){
                BuildingInfo buildingInfo = list.get(0);
                //获取楼栋表级别id  level  = 2
                Integer parentId = buildingInfo.getParentId();
                //设置楼栋id
                info.setBuildingId(parentId);
                //获取小区楼栋信息
                BuildingInfo bdo = new BuildingInfo();
                bdo.setId(parentId).setLevel(2);
                List<BuildingInfo> list1 = buildingInfoMapper.findList(bdo);
                if (CollectionUtil.isNotEmpty(list1)){
                    info.setResidentialId(list1.get(0).getParentId());
                }

            }
        }
        //家庭成员填写
        info.setFamilyId(0)
                .setSourceChannel(2)
                // TODO: 2022/4/23 暂时导入角色默认为1   即普通居民
                .setRoleId("1")
                .setRelationId("1")
                .setRegistered(2)
                .setCreateDate(new Date())
                .setUpdateDate(new Date());
        int row = inhabitantInfoMapper.insert(info);
        return row == 1 ? GeneralResponse.success() : GeneralResponse.fail();
    }


    /**
     * 更新居民信息
     * @param inhabitantInfoDto
     * @return
     */
    @Override
    @Transactional
    public GeneralResponse updateInhabitInfo(InhabitantInfoDto inhabitantInfoDto) {
        //判断身份证不能重复
        InhabitantInfo info = new InhabitantInfo();
        QueryWrapper<InhabitantInfo> wrapper = new QueryWrapper<>();
        if (StringUtil.isNotEmpty(inhabitantInfoDto.getIdentifyNo())){
            wrapper.eq("identifyNo",inhabitantInfoDto.getIdentifyNo());
            inhabitantInfoMapper.selectList(wrapper);
            List<InhabitantInfo> inhabitList =  inhabitantInfoMapper.selectList(wrapper);
            if (CollectionUtil.isNotEmpty(inhabitList)){
                for (InhabitantInfo tmp : inhabitList){
                    if (tmp.getId() != inhabitantInfoDto.getId()){
                       return GeneralResponse.fail(ApiGlobalErrorDefinition.USER_EXISTD);
                    }
                }
            }
            info.setIdentifyNo(inhabitantInfoDto.getIdentifyNo());
        }
        //更新居民信息

        if (StringUtil.isNotEmpty(inhabitantInfoDto.getUserName())){
            info.setUserName(inhabitantInfoDto.getUserName());
        }
        if (inhabitantInfoDto.getIdentifyType() != null){
            info.setIdentifyType(inhabitantInfoDto.getIdentifyType());
        }
        if (StringUtil.isNotEmpty(inhabitantInfoDto.getPhoneNumber())){
            info.setPhoneNumber(inhabitantInfoDto.getPhoneNumber());
        }
        info.setUpdateDate(new Date());
        //设置居民用户地址时，需根据传入的楼栋表 level = 3 的行id
        if (inhabitantInfoDto.getHouseId() != null){
            info.setHouseId(inhabitantInfoDto.getHouseId());
            BuildingInfo bo = new BuildingInfo();
            bo.setLevel(3);
            bo.setId(inhabitantInfoDto.getHouseId());
            //获取到房间号信息  housed
            List<BuildingInfo> list = buildingInfoMapper.findList(bo);
            if (CollectionUtil.isNotEmpty(list)){
                BuildingInfo buildingInfo = list.get(0);
                //获取楼栋表级别id  level  = 2
                Integer parentId = buildingInfo.getParentId();
                //设置楼栋id
                info.setBuildingId(parentId);
                //获取小区楼栋信息
                BuildingInfo bdo = new BuildingInfo();
                bdo.setId(parentId).setLevel(2);
                List<BuildingInfo> list1 = buildingInfoMapper.findList(bdo);
                if (CollectionUtil.isNotEmpty(list1)){
                    info.setResidentialId(list1.get(0).getParentId());
                }

            }
        }
        info.setId(inhabitantInfoDto.getId());
        info.setUpdateDate(new Date());
        int row  = inhabitantInfoMapper.updateInhabit(info);
        return row == 1 ? GeneralResponse.success() : GeneralResponse.fail();
    }
    /**
     * 删除居民信息
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteInhabitinfo(Integer id) {
        inhabitantInfoMapper.deleteById(id);
    }


    /**
     * 下载导出模板
     * @param inhabitInfoVos
     * @param response
     */
    @Override
    public void downloadInhbitModel(List<InhabitInfoVo> inhabitInfoVos, HttpServletResponse response) {
        // 导出数据，数据，数据类型，文件名称，表名，响应对象
        ExportExcelUtil.exportExcel(inhabitInfoVos, InhabitInfoVo.class,EXPORT_INHABIT_FILENAME,EXPORT_INHABIT_TITLE,response);
    }


    /**
     * 导出居民列表列表
     * @param neighborId   居委会表id
     * @param response
     */
    @Override
    public void exportInhabitInfo(Integer neighborId, HttpServletResponse response) {
        InhabitantInfoDto inhabitantInfoDto = new InhabitantInfoDto();
        inhabitantInfoDto.setNeighborhoodId(neighborId);
        List<InhabitInfoVo> inhabitList = inhabitantInfoMapper.findInhabitList(inhabitantInfoDto);
        //拼接家庭住址信息
        inhabitList.forEach(tmp ->{
            StringBuilder sb = new StringBuilder("");
            //组装小区/楼栋/房间号
            BuildingInfo bi = new BuildingInfo();
            bi.setId(tmp.getResidentialId())
                    .setLevel(1);
            List<BuildingInfo> clist = buildingInfoMapper.findList(bi);
            if (CollectionUtil.isNotEmpty(clist)){
                sb.append(clist.get(0).getName());
            }
            bi.setId(tmp.getBuildingId())
                    .setLevel(2);
            List<BuildingInfo> blist = buildingInfoMapper.findList(bi);
            if (CollectionUtil.isNotEmpty(blist)){
                sb.append(blist.get(0).getName());
            }
            bi.setId(tmp.getHouseId())
                    .setLevel(3);
            List<BuildingInfo> rlist = buildingInfoMapper.findList(bi);
            if (CollectionUtil.isNotEmpty(rlist)){
                sb.append(rlist.get(0).getName());
            }
            tmp.setAddress(sb.toString());
        });
        ExportExcelUtil.exportExcel(inhabitList,InhabitInfoVo.class,EXPORT_INHABIT_FILENAME,EXPORT_INHABIT_TITLE,response);
    }

    @Override
    @Transactional
    public void uploadInhabitList(Integer neighborId, MultipartFile multipartFile, HttpServletResponse response) throws Exception {

            //暂时模拟读取本地文件test
           // FileInputStream inputStream = new FileInputStream(new File("D:\\项目\\居委会所属居民信息模板-20220427.xlsx"));
            ImportParams params = new ImportParams();
            params.setTitleRows(1);
            params.setHeadRows(1);
            //解析导入列表
            List<InhabitInfoVo> inhabitInfoVos = ExcelImportUtil.importExcel(multipartFile.getInputStream(),
                    InhabitInfoVo.class, params);
            int count = 0; //初始化导入成功数量
            for (InhabitInfoVo tmp : inhabitInfoVos){
                try {
                    InhabitantInfoDto infoDto = new InhabitantInfoDto();
                    infoDto.setIdentifyNo(tmp.getIdentifyNo());
                    infoDto.setPhoneNumber(tmp.getPhoneNumber());
                    infoDto.setUserName(tmp.getUserName());
                    infoDto.setIdentifyType(tmp.getIdentifyType());
                    infoDto.setNeighborhoodId(neighborId);
                    String res = CheckParamUtil.checkNull(infoDto, Arrays.asList("userName", "phoneNumber", "identifyNo", "identifyType", "neighborhoodId"));
                    if (StringUtils.isNotEmpty(res)) continue;;
                    GeneralResponse generalResponse = addInhabitInfo(infoDto);
                    if (generalResponse.getCode().equals(GeneralResponse.CODE_SUCCESS)){
                        count++;
                    }

                } catch (Exception e) {
                   continue;
                }
            }
            log.info("上传居民信息excel列表成功，excel总数为{}条，成功{}条",inhabitInfoVos.size(),count);
    }


    /**
     * 获取单个居民的用户信息
     */
    @Override
    public List<InhabitInfoVo> getFamilylist(InhabitantInfoDto infoDto) {
        List<InhabitInfoVo> inhabitListById = inhabitantInfoMapper.getFamilylist(infoDto);

        for (InhabitInfoVo inhabitInfoVo : inhabitListById){
            StringBuilder sb = new StringBuilder("");
            //获取小区信息
            BuildingInfo buildingInfo = new BuildingInfo();
            buildingInfo.setId(inhabitInfoVo.getResidentialId())
                    .setLevel(1);
            List<BuildingInfo> list1 = buildingInfoMapper.findList(buildingInfo);
            if (CollectionUtil.isNotEmpty(list1)){
                sb.append(list1.get(0).getName());
            }
            //获取楼栋号信息
            BuildingInfo buildingNoInfo = new BuildingInfo();
            buildingNoInfo.setId(inhabitInfoVo.getBuildingId())
                    .setLevel(2);
            List<BuildingInfo> list2 = buildingInfoMapper.findList(buildingNoInfo);
            if (CollectionUtil.isNotEmpty(list2)){
                sb.append(list2.get(0).getName());
            }

            //获取房间号
            BuildingInfo roomNoInfo = new BuildingInfo();
            buildingNoInfo.setId(inhabitInfoVo.getHouseId())
                    .setLevel(3);
            List<BuildingInfo> list3 = buildingInfoMapper.findList(buildingNoInfo);
            if (CollectionUtil.isNotEmpty(list3)){
                sb.append(list3.get(0).getName());
            }
            inhabitInfoVo.setAddress(sb.toString());

        }
        return inhabitListById;
    }


    /**
     *
     * @param list
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public GeneralResponse batchModifyInhabit(List<InhabitantInfoDto> list) {

        int count = 0;   //初始化待修改的人员数量
        //更新家庭成员相关信息
        for (InhabitantInfoDto tmp : list){
            GeneralResponse generalResponse = updateInhabitInfo(tmp);
            if (GeneralResponse.success().getCode().equals(generalResponse.getCode())){
                count++;
            }
        }
        log.info("批量修改居民信息total = {},success = {}",list.size(),count);
        //return count == list.size() ? GeneralResponse.success() : GeneralResponse.fail();
        return GeneralResponse.success();
    }

    @Override
    public long getNotRegisterInhabitNum(Integer neighobrId) {
        InhabitantInfo info = new InhabitantInfo();
        info.setNeighborhoodId(neighobrId);
        info.setRegistered(2);
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.setEntity(info);
        Map<Object, Boolean> map = new HashMap<>();
        List<InhabitantInfo> list = inhabitantInfoMapper.selectList(wrapper);
        List<InhabitantInfo> distinct= list.stream().filter(i -> map.putIfAbsent(i.getIdentifyNo(), Boolean.TRUE) == null).collect(Collectors.toList());
        return distinct.size();
    }


    public static void main(String[] args) throws Exception {
        //new InhabitInfoServiceImpl().uploadInhabitList(2,null,null);
        InhabitantInfoDto infoDto = new InhabitantInfoDto();
        infoDto.setIdentifyNo("1111");
        infoDto.setPhoneNumber("2222");
        infoDto.setUserName("2222");
        infoDto.setIdentifyType(1);
        infoDto.setNeighborhoodId(1);
        String s = CheckParamUtil.checkNull(infoDto, Arrays.asList("userName", "phoneNumber", "identifyNo", "identifyType", "neighborhoodId"));
        System.out.println(s);
    }

}
